# -*- coding: utf8 -*-

"""
    监听指定目录下的文件变化
"""
import os
import sys
import time
import copy
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

import logging
logger = logging.getLogger('bit_torrent')


class FileEventHandler(FileSystemEventHandler):
    def __init__(self, folder_monitor, torrent_folder):
        FileSystemEventHandler.__init__(self)
        self.folder_monitor = folder_monitor
        self.torrent_folder = torrent_folder

    def on_moved(self, event):
        if event.is_directory:
            logger.info('忽略 目录移动 {0} -> {1}'.format(event.src_path, event.dest_path))
        else:
            logger.info('文件移动 {0} -> {1}'.format(event.src_path, event.dest_path))
            self.folder_monitor._notify_cancle_distribute_file(event.src_path, self.torrent_folder)
            self.folder_monitor._notify_distribute_file(event.dest_path, self.torrent_folder, rebuild_torrent_file=True)

    def on_created(self, event):
        if event.is_directory:
            logger.info('忽略 目录创建:{0}'.format(event.src_path))
        else:
            logger.info('文件创建:{0}'.format(event.src_path))
            self.folder_monitor._notify_distribute_file(event.src_path, self.torrent_folder, rebuild_torrent_file=True)

    def on_deleted(self, event):
        if event.is_directory:
            logger.info('忽略 目录删除:{0}'.format(event.src_path))
        else:
            logger.info('文件删除:{0}'.format(event.src_path))
            self.folder_monitor._notify_cancle_distribute_file(event.src_path, self.torrent_folder)

    def on_modified(self, event):
        if event.is_directory:
            logger.info('忽略 目录修改:{0}'.format(event.src_path))
        else:
            logger.info('文件修改:{0}'.format(event.src_path))
            self.folder_monitor._notify_redistribute_file(event.src_path, self.torrent_folder)


class FolderMonitor(object):
    def __init__(self, **kwargs):
        super(FolderMonitor, self).__init__()
        self._folder_category_path_dict = {}     # 被监控的文件夹
        self._torrent_folder_root = ''          # 保存torrent的根目录
        self._pipe = (None, None)

        if 'folder_category_path_dict' in kwargs:
            self.folder_category_path_dict = kwargs['folder_category_path_dict']

        if 'torrent_folder_root' in kwargs:
            self.torrent_folder_root = kwargs['torrent_folder_root']

        if 'pipe' in kwargs:
            self.pipe = kwargs['pipe']

    @property
    def folder_category_path_dict(self):
        return self._folder_category_path_dict

    @folder_category_path_dict.setter
    def folder_category_path_dict(self, value):
        # self._folder_category_path_dict = copy.deepcopy(value)
        for name, path in value.items():
            self._folder_category_path_dict[name] = os.path.abspath(path)

    @property
    def torrent_folder_root(self):
        return self._torrent_folder_root

    @torrent_folder_root.setter
    def torrent_folder_root(self, value):
        self._torrent_folder_root = os.path.abspath(value)

    @property
    def pipe(self):
        return self._pipe

    @pipe.setter
    def pipe(self, value):
        self._pipe = value

    def _notify_distribute_file(self, file_path, torrent_folder, rebuild_torrent_file=False):
        """通知bit_torrent 分发文件
        
        Arguments:
            file_path {string} -- 文件位置
            torrent_folder {string} -- torrent 保持目录
        """

        print(file_path)
        self._pipe.send({
            'type': 'DISTRIBUTE_FILE',
            'data': {
                'file_path': file_path,
                'torrent_folder': torrent_folder,
                'rebuild_torrent_file': rebuild_torrent_file
            }
        })

    def _notify_redistribute_file(self, file_path, torrent_folder):
        """通知bit_torrent 重新分发文件
        
        Arguments:
            file_path {string} -- 文件位置
            torrent_folder {string} -- torrent 保持目录
        """

        self._pipe.send({
            'type': 'REDISTRIBUTE_FILE',
            'data': {
                'file_path': file_path,
                'torrent_folder': torrent_folder,
            }
        })

    def _notify_cancle_distribute_file(self, file_path, torrent_folder):
        """通知bit_torrent 取消分发文件
        
        Arguments:
            file_path {string} -- 文件位置
            torrent_folder {string} -- torrent 保持目录
        """

        self._pipe.send({
            'type': 'CANCLE_DISTRIBUTE_FILE',
            'data': {
                'file_path': file_path,
                'torrent_folder': torrent_folder
            }
        })

    def run_infinite(self):
        """监听folder_monitor_path_dict中的文件夹,在被监控的文件夹中的文件会被分发
        """

        assert self._folder_category_path_dict, '请先设置 folder_category_path_dict'
        assert self._torrent_folder_root, '请先设置 torrent_folder_root'

        logger.info('setting: {}'.format(self._folder_category_path_dict))

        observers = []
        for name, path in self._folder_category_path_dict.items():
            # 在torrent_folder下创建对应的目录
            torrent_folder = os.path.join(self._torrent_folder_root, name)
            if not os.path.isdir(torrent_folder):
                os.makedirs(torrent_folder)

            files = os.listdir(path)
            files = sorted(files)
            for file in files:
                file_path = os.path.join(path, file)
                if not os.path.isfile(file_path):
                    continue

                # 将文件添加到分发队列
                self._notify_distribute_file(file_path, torrent_folder)

            observer = Observer()
            event_handler = FileEventHandler(self, torrent_folder)
            observer.schedule(event_handler, path, recursive=False)
            observer.start()
            observers.append(observer)

        # try:
        #     while True:
        #         time.sleep(1)
        # except KeyboardInterrupt:
        #     for observer in observers:
        #         observer.stop()

        logger.debug('watch dog run.')
        for observer in observers:
            observer.join()
        logger.warning('已停止文件监听.')
